package com.mark.security;

import com.mark.common.ServerResponse;
import com.mark.web.sys.common.enmus.UserStateEnum;
import com.mark.web.sys.entity.po.User;
import com.mark.web.sys.service.IUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @Description:
 * @Author: Kingsley
 * @CreateDate: 2019/1/1 20:00
 * @Version: 2.0
 * @Copyright : 豆浆油条个人非正式工作室
 */
public class ShiroRealm extends AuthorizingRealm{

    @Resource
    private IUserService iUserService;

    /**
     *  授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        User user = (User) principalCollection.getPrimaryPrincipal();
        if(user != null){
            SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
            Set<String> roles = new HashSet<>();
            roles.add("admin");
            //用户角色
            info.setRoles(roles);

            List<String> permissionList = new ArrayList<>();
            permissionList.add("4444");
            //用户权限
            info.addStringPermissions(permissionList);
            return info;
        }
        return null;
    }

    /**
     * 登录认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        UsernamePasswordToken loginToken = (UsernamePasswordToken) authenticationToken;
        //获取登录的类型，类型的值，登录密码
        String type = loginToken.getType();
        String typeValue = loginToken.getTypeValue();
        String pwd = new String(loginToken.getPassword());

        ServerResponse<User> response = iUserService.login(type, typeValue, pwd);
        //用户输入信息校验不通过
        if(!response.isSuccess()){
            throw new UnknownAccountException(response.getMsg());
        }
        if(response.isSuccess()) {
            User user = response.getData();
            if(user.getEnableStatus() == UserStateEnum.ERROR.getState()){
                throw new LockedAccountException(UserStateEnum.ERROR.getStateInfo());
            }
            //SimpleAuthenticationInfo()中的三个参数
            //1 principal ：认证实体信息，可以是username，也可以是数据库中对应的实体类对象
            //2 credentials ：密码
            //3 realmName :当前realm对象的名称，调用父类的getName()方法便可获取
            return new SimpleAuthenticationInfo(user, user.getPassword(), getName());
        }
        throw new AuthenticationException();
    }
}
